package main

import (
	"fmt"
	"strconv"
	"strings"
	"unsafe"
)

//常量取不到地址

//数组地址即为第一个元素的地址：pArr == p1
//数组在内存中是连续的字节 n1+4=n2
func Demo_ArrayAddress() {

	arr := [4]int32{3, 9, 6, 8}
	pArr, p1, p2, p3 := &arr, &arr[0], &arr[1], &arr[2]
	start := uintptr((unsafe.Pointer(pArr)))

	itemLen := unsafe.Sizeof(arr[0]) //int32 4个字节
	n1 := (*int32)(unsafe.Pointer(start))
	n2 := (*int32)(unsafe.Pointer(start + itemLen))
	n3 := (*int32)(unsafe.Pointer(start + itemLen*2))

	fmt.Printf("数组内存开始地址:%v\n", start)
	fmt.Printf("数组第一个元素:%d 地址:%v 二进制:%s\n", *n1, uintptr((unsafe.Pointer(p1))), Int32ToBinary(*n1))
	fmt.Printf("数组第二个元素:%d 地址:%v 二进制:%s\n", *n2, uintptr((unsafe.Pointer(p2))), Int32ToBinary(*n2))
	fmt.Printf("数组第三个元素:%d 地址:%v 二进制:%s\n", *n3, uintptr((unsafe.Pointer(p3))), Int32ToBinary(*n3))
}

//假设1
//把[4]int32 => [2]int64
//即数组内存地址为：
// 					3										9									6								8
//00000000 00000000 00000000 00000011 |00000000 00000000 00000000 00001001 |00000000 00000000 00000000 00000110 |00000000 00000000 00000000 00001000
//									12884901897							   |								25769803784
func Demo_ArrayAddress_int32ToInt64() {
	arr := [4]int32{3, 9, 6, 8}
	//数组内存二进制为
	for i := 0; i < len(arr); i++ {
		if i != 0 {
			fmt.Printf("|")
		}
		fmt.Printf(Int32ToBinary(arr[i]))
	}
	fmt.Println()

	arr_result := [2]int64{}
	//in64[0]
	if arr_result_1, err := BinaryToInt64(Int32ToBinary(arr[0]) + Int32ToBinary(arr[1])); err == nil {
		arr_result[0] = arr_result_1
	}

	if arr_result_2, err := BinaryToInt64(Int32ToBinary(arr[2]) + Int32ToBinary(arr[3])); err == nil {
		arr_result[1] = arr_result_2
	}

	//打印结果
	for i := 0; i < len(arr_result); i++ {
		if i != 0 {
			fmt.Printf("|")
		}
		fmt.Printf(Int64ToBinary(arr_result[i]))
	}
	fmt.Println()
	fmt.Printf("%v => %v\n", arr, arr_result)
	//00000000 00000000 00000000 00000011 |00000000 00000000 00000000 00001001 |00000000 00000000 00000000 00000110 |00000000 00000000 00000000 00001000
	//00000000 00000000 00000000 00000011 00000000 00000000 00000000 00001001 |00000000 00000000 00000000 00000110 00000000 00000000 00000000 00001000
	//[3 9 6 8] => [12884901897 25769803784]
	//假设成立
}

//假设2
//同一台机器 两套程序可以通过传递指针 内存共享数据
func Demo_ArrayAddress_sharedData() {

}

func main() {
	//Demo_ArrayAddress()
	Demo_ArrayAddress_int32ToInt64()
	//Demo_ArrayAddress_sharedData()
}

func Int32ToBinary(num int32) string {
	str := fmt.Sprintf("%032b", num)
	return formatBinary(str)
}

func Int64ToBinary(num int64) string {
	str := fmt.Sprintf("%064b", num)
	return formatBinary(str)
}

func formatBinary(binary string) string {
	returnStr := ""
	for index, str := range binary {
		if (index+1)%8 == 0 && index != len(binary)-1 {
			returnStr += string(str) + " "
			continue
		}
		returnStr += string(str)
	}
	return returnStr
}

func BinaryToInt32(binary string) (int32, error) {
	binary = strings.ReplaceAll(binary, " ", "")
	int64Num, err := strconv.ParseInt(binary, 2, 32)
	if err != nil {
		return 0, err
	}
	return int32(int64Num), nil
}
func BinaryToInt64(binary string) (int64, error) {
	binary = strings.ReplaceAll(binary, " ", "")
	return strconv.ParseInt(binary, 2, 64)
}
